home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / C Internet Config / IC Application Source ƒ / C Source ƒ / IC Text Whats.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-01  |  11.0 KB  |  470 lines  |  [TEXT/SPM ]

  1. /*
  2.     IC Text Whats.c
  3.     
  4. */
  5.  
  6. #include <Scrap.h>
  7.  
  8. #include "IC Globals.h"
  9.  
  10. #include "IC Window Globals.h"
  11. #include "IC Types.h"
  12. #include "IC API.h"
  13. #include "IC Globals.h"
  14. #include "IC Misc Subs.h"
  15. #include "IC Subs.h"
  16. #include "IC Text.h"
  17. #include "IC Dialogs.h"
  18. #include "IC Document.h"
  19. #include "IC Text Whats.h"
  20.  
  21. pascal void DrawTextProc(DialogPtr window,short item){
  22.     Rect r;
  23.     short savefont,savemode,savesize;
  24.     Style saveface;
  25.     
  26.     savefont=window->txFont;
  27.     saveface=window->txFace;
  28.     savemode=window->txMode;
  29.     savesize=window->txSize;
  30.     
  31.     TextDraw(WindowInfo[GetWindowType(window)].items[item]->data);
  32.     
  33.     GetDItemRect(window,item,&r);
  34.     InsetRect(&r,-3,-3);
  35.     PenNormal();
  36.     FrameRect(&r);
  37.     
  38.     TextFont(savefont);
  39.     TextFace(saveface);
  40.     TextMode(savemode);
  41.     TextSize(savesize);
  42. }
  43.  
  44. Boolean HaveTextSelection(WindowType wt){
  45.     long start_sel,end_sel;
  46.     Boolean ret=false;
  47.     
  48.     if (GetSelectedItem(wt)>0){
  49.         TextGetSelect(WindowInfo[wt].items[GetSelectedItem(wt)]->data,&start_sel,&end_sel);
  50.         ret=(start_sel!=end_sel);
  51.     }
  52.     
  53.     return ret;
  54. }
  55.  
  56. void AdjustTextMenu(WindowType wt){
  57.     Boolean enable_cut=false,enable_paste=false,enable_select_all=false;
  58.     Boolean enable_undo=false;
  59.     long offset;
  60.     MenuHandle mh;
  61.     Handle texth;
  62.     long text_size;
  63.     short search_text;
  64.     long cr_pos;
  65.     short item;
  66.     OSErr err;
  67.     long sel_start,sel_end;
  68.     
  69.     item=GetSelectedItem(wt);
  70.     if ((wt!=WT_None)&&(item>0)){
  71.         enable_cut=HaveTextSelection(wt);
  72.         offset=0;
  73.         enable_paste=(GetScrap((Handle)0,'TEXT',&offset)>0);
  74.         TextGetSelect(WindowInfo[wt].items[item]->data,&sel_start,&sel_end);
  75.         TextGetSize(WindowInfo[wt].items[item]->data,&text_size);
  76.         enable_select_all=((sel_start!=0)||(sel_end!=text_size));
  77.     }
  78.     
  79.     // deal with the nasty paste problem, ie preventing them pasting CRs into single line fields
  80.     if ((enable_paste)&&(WindowInfo[wt].items[item]->flags&(1<<tf_single_line))){
  81.         texth=NewHandle(0);
  82.         err=MemError();
  83.         if (err==noErr){
  84.             offset=0;
  85.             text_size=GetScrap(texth,'TEXT',&offset);
  86.             if (text_size>0){
  87.                 search_text=0x0d0d;
  88.                 cr_pos=Munger(texth,0,(Ptr)&search_text,1,(Ptr)0,0);
  89.                 
  90.                 if (cr_pos<0)
  91.                     enable_paste=true;
  92.                 else if (cr_pos==text_size-1)
  93.                     enable_paste=(cr_pos>0);
  94.                 else
  95.                     enable_paste=false;
  96.             } else
  97.                 enable_paste=false;
  98.         }
  99.         if (texth!=(Handle)0)
  100.             DisposeHandle((Handle)texth);
  101.     }
  102.     
  103.     // deal with locked items
  104.     if (item>0){
  105.         if (IsLocked(wt,item)){
  106.             enable_paste=false;
  107.             enable_cut=false;
  108.         }
  109.     }
  110.     
  111.     // hit the menu items
  112.     mh=GetMenuHandle(M_Edit);
  113.     SetItemEnable(mh,EM_Undo,enable_undo);
  114.     SetItemEnable(mh,EM_Cut,enable_cut);
  115.     SetItemEnable(mh,EM_Copy,enable_cut);
  116.     SetItemEnable(mh,EM_Paste,enable_paste);
  117.     SetItemEnable(mh,EM_Clear,enable_cut);
  118.     SetItemEnable(mh,EM_SelectAll,enable_select_all);
  119. }
  120.  
  121. void JustSelectTextItem(WindowType wt,short item){
  122.     if (GetSelectedItem(wt)>0)
  123.         TextActivate(WindowInfo[wt].items[GetSelectedItem(wt)]->data,false);
  124.     TextActivate(WindowInfo[wt].items[item]->data,((FrontWindow()==WindowInfo[wt].window)&&(InForeground())));
  125.     WindowInfo[wt].selected_item=item;
  126. }
  127.  
  128. void SelectTextItem(WindowType wt,short item){
  129.     JustSelectTextItem(wt,item);
  130.     TextSetSelect(WindowInfo[wt].items[item]->data,0,32767);
  131. }
  132.  
  133. void DoTextMenu(WindowType wt,short menuitem){
  134.     Ptr data;
  135.     Handle texth;
  136.     long offset,cr_pos,text_size;
  137.     short search_text,item;
  138.     
  139.     item=GetSelectedItem(wt);
  140.     data=WindowInfo[wt].items[item]->data;
  141.     
  142.     switch(menuitem){
  143.         case EM_Undo:
  144.             break;
  145.         case EM_Cut:
  146.             TextCut(data);
  147.             break;
  148.         case EM_Copy:
  149.             TextCopy(data);
  150.             break;
  151.         case EM_Paste:
  152.             if (IsLocked(wt,item))
  153.                 LockedAlert(wt,item);
  154.             else {
  155.                 if (WindowInfo[wt].items[item]->flags&(1<<tf_single_line)){
  156.                     texth=NewHandle(0);
  157.                     if (texth!=(Handle)0){
  158.                         offset=0;
  159.                         text_size=GetScrap(texth,'TEXT',&offset);
  160.                         if (text_size>0){
  161.                             search_text=0x0d0d;
  162.                             cr_pos=Munger(texth,0,(Ptr)&search_text,1,(Ptr)0,0);
  163.                             if (cr_pos>0)
  164.                                 SetHandleSize(texth,cr_pos);
  165.                             TextClear(data);
  166.                             TextInsert(data,texth);
  167.                         }
  168.                         DisposeHandle(texth);
  169.                     }
  170.                 } else {
  171.                     TextPaste(data);
  172.                 }
  173.             }
  174.             break;
  175.         case EM_Clear:
  176.             if (IsLocked(wt,item))
  177.                 LockedAlert(wt,item);
  178.             else
  179.                 TextClear(data);
  180.             break;
  181.         case EM_SelectAll:
  182.             TextSetSelect(data,0,32767);
  183.             break;
  184.         default:
  185.             break;
  186.     }
  187. }
  188.  
  189. Boolean BlockCompare(Ptr lhs,Ptr rhs,long size){
  190.     register long i=0;
  191.     register unsigned long* ul,* ur;
  192.     Boolean ret=false;
  193.     long csize=size/sizeof(unsigned long);
  194.     short left=size%sizeof(unsigned long); // leftover to compare...
  195.     
  196.     // do fast comparison on long values (compare 4 bytes at a time)
  197.     ul=(unsigned long*)lhs;
  198.     ur=(unsigned long*)rhs;
  199.     
  200.     while (i<csize){
  201.         if (*ul!=*ur)
  202.             return false;
  203.         ul++;
  204.         ur++;
  205.         i++;
  206.     }
  207.     
  208.     // if we get here, the major chunk of memory matched
  209.     // the only thing left to check is any odd bytes trailing at the end of the blocks
  210.     if (left){
  211.         // odd size being compared
  212.         register unsigned char* cl,*cr,ct;
  213.         
  214.         cl=(unsigned char*)ul;
  215.         cr=(unsigned char*)ur;
  216.         
  217.         for (ct=0;ct<left;ct++){
  218.             if (*cl!=*cr)
  219.                 return false;
  220.             cl++;
  221.             cr++;
  222.         }
  223.     }
  224.     
  225.     // everything checked out! return true
  226.     return true;
  227. }
  228.  
  229. void ScrambleHandle(Handle texth){
  230.     register long l=0L,ct=GetHandleSize(texth);
  231.     register unsigned char* up;
  232.     unsigned char uc,val,val2,u4,u2,u3;
  233.     
  234.     up=(unsigned char*)*texth;
  235.     
  236.     while (l<ct){
  237.         *up=(*up)^(0x55+(l+1));
  238.  
  239.         up++;
  240.         l++;
  241.     }
  242. }
  243.  
  244. void BlockFill(Ptr p,long size,char value){
  245.     union {
  246.         unsigned long lval;
  247.         char cval[4];
  248.     } block;
  249.     register long i=0;
  250.     register unsigned long* ul;
  251.     long csize=size/sizeof(unsigned long);
  252.     short left=size%sizeof(unsigned long); // leftover to compare...
  253.     
  254.     // fill up the block
  255.     block.cval[0]=block.cval[1]=block.cval[2]=block.cval[3]=value;
  256.     
  257.     // do fast set with long values (compare 4 bytes at a time)
  258.     ul=(unsigned long*)p;
  259.     
  260.     while (i<csize){
  261.         *ul=block.lval;
  262.         ul++;
  263.         i++;
  264.     }
  265.     
  266.     // if we get here, the major chunk of memory has been set
  267.     // the only thing left to do is any odd bytes trailing at the end of the blocks
  268.     if (left){
  269.         // odd size being compared
  270.         register unsigned char* cl,ct;
  271.         
  272.         cl=(unsigned char*)ul;
  273.         
  274.         for (ct=0;ct<left;ct++){
  275.             cl[ct]=value;
  276.         }
  277.     }
  278. }
  279.  
  280. OSErr WhatOpenText(WindowType wt,short item){
  281.     OSErr err;
  282.     Str31 key;
  283.     long attr;
  284.     Handle texth;
  285.     long junk,flags;
  286.     Boolean pstring,scrambled;
  287.     short font,size;
  288.     Rect r;
  289.     
  290.     WindowInfo[wt].items[item]->data=(Ptr)0;
  291.     WindowInfo[wt].items[item]->spare_data=(Ptr)0;
  292.     texth=(Handle)0;
  293.     
  294.     SetPString(key,1,WindowInfo[wt].items[item]->key);
  295.     flags=WindowInfo[wt].items[item]->flags;
  296.     pstring=flags&(1<<tf_pstring);
  297.     scrambled=flags&(1<<tf_scrambled);
  298.     
  299.     if (flags&(1<<tf_monospace)){
  300.         font=monaco;
  301.         size=9;
  302.     } else {
  303.         font=systemFont;
  304.         size=12;
  305.     }
  306.     
  307.     err=ICMapErr(ICGetPrefHandle(GetInstance(),key,&attr,&texth));
  308.     if (err==noErr){
  309.         ProcessAttributes(wt,item,attr);
  310.         if (pstring)
  311.             Munger(texth,0,(Ptr)0,1,(Ptr)&junk,0);// strip the first char
  312.         if (scrambled)
  313.             ScrambleHandle(texth);
  314.         err=TextCreate(&(WindowInfo[wt].items[item]->data),WindowInfo[wt].window,item,font,
  315.             size,IsLocked(wt,item));
  316.     }
  317.     if (err==noErr){
  318.         SetDItemHandle(WindowInfo[wt].window,item,(Handle)gDrawTextProc);
  319.         junk=GetHandleSize(texth);
  320.         // (*texth)[junk]=0;
  321.         TextInsert(WindowInfo[wt].items[item]->data,texth);
  322.     }
  323.     
  324.     // build password dialog string
  325.     if ((err==noErr)&&(scrambled)){
  326.         WindowInfo[wt].items[item]->spare_data=WindowInfo[wt].items[item]->data;
  327.         WindowInfo[wt].items[item]->data=(Ptr)0;
  328.         GetDItemRect(WindowInfo[wt].window,item,&r);
  329.         OffsetRect(&r,16000,0);
  330.         TextMove(WindowInfo[wt].items[item]->spare_data,&r);
  331.         BlockFill(*texth,GetHandleSize(texth),'•');
  332.         
  333.         err=TextCreate(&(WindowInfo[wt].items[item]->data),WindowInfo[wt].window,item,font,
  334.             size,IsLocked(wt,item));
  335.         
  336.         if (err==noErr)
  337.             TextInsert(WindowInfo[wt].items[item]->data,texth);
  338.     }
  339.     
  340.     if (texth!=(Handle)0)
  341.         DisposeHandle(texth);
  342.     
  343.     return err;
  344. }
  345.  
  346. OSErr WhatFlushText(WindowType wt,short item){
  347.     OSErr err;
  348.     Str31 key;
  349.     Handle texth=(Handle)0,oldtexth=(Handle)0;
  350.     long attr,flags,texts,oldtexts;
  351.     short i;
  352.     Boolean pstring,scrambled;
  353.     
  354.     texth=oldtexth=(Handle)0;
  355.     SetPString(key,1,WindowInfo[wt].items[item]->key);
  356.     flags=WindowInfo[wt].items[item]->flags;
  357.     pstring=flags&(1<<tf_pstring);
  358.     scrambled=flags&(1<<tf_scrambled);
  359.     err=ICMapErr(ICGetPrefHandle(GetInstance(),key,&attr,&oldtexth));
  360.     if (err==noErr){
  361.         if ((pstring)&&(GetHandleSize(oldtexth)==0)){
  362.             // pref is non-existent or empty, turn oldtext into a handle for an empty pascal string
  363.             SetHandleSize(oldtexth,1);
  364.             err=MemError();
  365.             if (err==noErr)
  366.                 **oldtexth=0; // terminate the empty pstring
  367.         }
  368.     }
  369.     if (err==noErr){
  370.         texth=NewHandle(0);
  371.         err=MemError();
  372.     }
  373.     
  374.     if (err==noErr){
  375.         if (scrambled){
  376.             TextGet(WindowInfo[wt].items[item]->spare_data,texth);
  377.             ScrambleHandle(texth);
  378.         } else
  379.             TextGet(WindowInfo[wt].items[item]->data,texth);
  380.         if (pstring){
  381.             if (GetHandleSize(texth)>255)
  382.                 SetHandleSize(texth,255);
  383.             i=GetHandleSize(texth)*0x0101; // puts it into both bytes!
  384.             // insert the size byte into the handle at position zero
  385.             Munger(texth,0L,(Ptr)0,0L,&i,1);// if this errors, we lose data
  386.         }
  387.         // should it go out to the prefs file?
  388.         texts=GetHandleSize(texth);
  389.         oldtexts=GetHandleSize(oldtexth);
  390.         {
  391.             Boolean islocked=IsLocked(wt,item);
  392.             Boolean sameSize=(texts==oldtexts);
  393.             Boolean sameText=true;
  394.             
  395.             if (sameSize) // only check the text if the sizes are the same
  396.                 sameText=BlockCompare(*texth,*oldtexth,texts);
  397.             
  398.             if (islocked){
  399.                 // can't update the doc, it is a locked field
  400.             } else if (sameSize&&sameText){
  401.                 // nothing changed, so don't update the doc
  402.             } else {
  403.                 // either the size or text is different, update the doc
  404.                 
  405.                 err=ICMapErr(ICSetPrefHandle(GetInstance(),key,ICattr_no_change,texth));
  406.                 
  407.                 if (err==noErr)
  408.                     DirtyDocument();
  409.             }
  410.         }
  411.     }
  412.     if (texth!=(Handle)0)
  413.         DisposeHandle(texth);
  414.     if (oldtexth!=(Handle)0)
  415.         DisposeHandle(oldtexth);
  416.     
  417.     return err;
  418. }
  419.  
  420. OSErr WhatCloseText(WindowType wt,short item){
  421.     long flags;
  422.     Boolean scrambled;
  423.     
  424.     flags=WindowInfo[wt].items[item]->flags;
  425.     scrambled=flags&(1<<tf_scrambled);
  426.     TextDestroy(&(WindowInfo[wt].items[item]->data));
  427.     if (scrambled)
  428.         TextDestroy(&(WindowInfo[wt].items[item]->spare_data));
  429.     return noErr;
  430. }
  431.  
  432. OSErr WhatClickText(WindowType wt,short item,EventRecord* er){
  433.     JustSelectTextItem(wt,item);
  434.     TextClick(WindowInfo[wt].items[item]->data,er);
  435.     return noErr;
  436. }
  437.  
  438. OSErr WhatKeyText(WindowType wt,short item,EventRecord* er){
  439.     long flags;
  440.     Boolean scrambled,single_line;
  441.     char ch;
  442.     long sel_start,sel_end;
  443.     
  444.     flags=WindowInfo[wt].items[item]->flags;
  445.     scrambled=flags&(1<<tf_scrambled);
  446.     single_line=flags&(1<<tf_single_line);
  447.     ch=(er->message&charCodeMask)&0xff;
  448.     
  449.     // if a return on a single line or whitespace with scrambled
  450.     if (((single_line)&&(ch==13))||((scrambled)&&(ch!=8)&&(ch<' ')))
  451.         SysBeep(1);
  452.     else {
  453.         if ((IsLocked(wt,item))&&(DirtyKey(ch)))
  454.             LockedAlert(wt,item);
  455.         else {
  456.             if (scrambled){
  457.                 TextGetSelect(WindowInfo[wt].items[item]->data,&sel_start,&sel_end);
  458.                 TextSetSelect(WindowInfo[wt].items[item]->spare_data,sel_start,sel_end);
  459.                 TextKey(WindowInfo[wt].items[item]->spare_data,er);
  460.                 if ((ch!=8)&&(DirtyKey(ch)))
  461.                     er->message='•';
  462.             }
  463.             
  464.             TextKey(WindowInfo[wt].items[item]->data,er);
  465.         }
  466.     }
  467.     
  468.     return noErr;
  469. }
  470.